package com.lpb.spring.test1;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * 字符串操作辅助类 extends org.apache.commons.lang.StringUtils
 *
 * @see org.apache.commons.lang3.StringEscapeUtils
 */
public abstract class StringUtils extends org.apache.commons.lang3.StringUtils {
    public static final String[][] options = new String[20][20];

    static {
        for (int i = 0; i < options.length; i++) {
            options[i][0] = Character.toString((char) (65 + i));
            for (int j = 1; j < options[i].length; j++) {
                options[i][j] = Character.toString((char) (65 + i)) + j;
            }
        }
    }

    /**
     * 用于批量操作是处理前台传入的id字符串
     * eg:1,2,3,4,5
     *
     * @return [1, 2, 3, 4, 5]
     */
    public static List<Long> convertIds(String idStr) {
        return Arrays.stream(idStr.split(",")).map(Long::valueOf).collect(Collectors.toList());
    }

    private static Map<String, String> field2columns = new HashMap<>();

    /**
     * 将userName==》USER_NAME
     *
     * @param fieldName 属性名
     * @return
     */
    public static String field2ColumnName(String fieldName) {
        String column = field2columns.get(fieldName);
        if (isBlank(column)) {
            if (fieldName.contains("_")) {
                column = fieldName.toUpperCase();
            } else {
                Matcher matcher = Pattern.compile("[A-Z][a-z0-9]*").matcher(fieldName);
                String columnName = fieldName;
                while (matcher.find()) {
                    String matches = matcher.group();
                    columnName = columnName.replace(matches, (matcher.start() == 0 ? "" : "_") + matches);
                }
                column = columnName.toUpperCase();
            }
            field2columns.put(fieldName, column);
        }
        return column;
    }
    /**
     * 将USER_NAME==》userName
     *
     * @param columnName 字段名
     * @return
     */
    public static String column2FieldName(String columnName) {
        String field = field2columns.get(columnName);
        if (isBlank(field)) {
            if (!columnName.contains("_")) {
                field = columnName.toLowerCase();
            } else {
                field = Arrays.stream(columnName.split("_")).map(e -> {
                    String r = e.toLowerCase();
                    if (columnName.indexOf(e) != 0) {
                        String first = String.valueOf(r.charAt(0));
                        r = r.replaceFirst(first, first.toUpperCase());
                    }
                    return r;
                }).collect(Collectors.joining());
            }
            field2columns.put(columnName, field);
        }
        return field;
    }

    /**
     * 3,‘A’ ==> "AAA"
     *
     * @param count
     * @return
     */
    public static String replenish(int count, CharSequence character) {
        return join(Collections.nCopies(count, character), EMPTY);
    }
    /**
     * 1,4 ==> 0001
     *
     * @param seq
     * @param count
     * @return
     */
    public static String generateCode(BigInteger seq, int count) {
        String code = String.valueOf(seq);
        return replenish(count - code.length(), "0") + code;
    }

    /**
     * 判定某个字符串是否以某些字符串开头
     *
     * @param str
     * @param prefs
     * @return
     */
    public static boolean startsWithOr(String str, String... prefs) {
        for (String pref : prefs) {
            if (str.startsWith(pref)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取UUID
     *
     * @return
     */
    public static String uuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 是否为邮箱
     *
     * @param str
     * @return
     */
    public static boolean isEmail(String str) {
        return isNotBlank(str) && str.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
    }

    /**
     * 是否是整数
     *
     * @param str
     * @return
     */
    public static boolean isInt(String str) {
        return isNotBlank(str) && str.matches("^[-]?\\d+$");
    }

    /**
     * 是否是中文
     *
     * @param str
     * @return
     */
    public static boolean isChinese(String str) {
        return isNotBlank(str) && str.matches("^[\u4e00-\u9fa5]{0,}$");
    }

    /**
     * 是否是手机号
     *
     * @param str
     * @return
     */
    public static boolean isPhoneNum(String str) {
        return isNotBlank(str) && str.matches("^(\\+\\d{2})?(1[2-9][0-9])\\d{8}$");
    }

    /***
     *  000001 ==> 000002
     * @param code
     * @return
     */
    public static String nextCode(String code) {
        return generateCode(new BigInteger(code).add(BigInteger.ONE), code.length());
    }

    /**
     * 0,0 ==> A
     * 0,1 ==> A_1
     *
     * @param xy
     * @return
     */
    public static String getOption(String xy) {
        if (xy.contains(",")) {
            String[] xys = xy.split(",");
            return options[Integer.parseInt(xys[0].trim())][Integer.parseInt(xys[1].trim())];
        } else {
            return options[Integer.parseInt(xy.trim())][0];
        }
    }

    /**
     * 0,0 ==> a
     * 0,1 ==> a1
     *
     * @param xy
     * @return
     */
    public static String getField(String xy) {
        return column2FieldName(getOption(xy));
    }


    public static String digit2chinese(int digit) {
        String si = String.valueOf(digit);
        String[] chineseDigits = new String[]{"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        String sd = "";
        if (si.length() == 1) {
            sd +=chineseDigits[digit];
            return sd;
        } else if (si.length() == 2) {
            if (Objects.equals(si.substring(0, 1), '1')) {
                sd += '十';
            } else {
                sd += (chineseDigits[digit / 10] + '十');
            }
            sd += digit2chinese(digit % 10);
        } else if (si.length() == 3) {
            sd += (chineseDigits[digit / 100] + '百');
            if (String.valueOf(digit % 100).length() < 2) {
                sd += '零';
            }
            sd += digit2chinese(digit % 100);
        } else if (si.length() == 4) {
            sd += (chineseDigits[digit / 1000] + '千');
            if (String.valueOf(digit % 1000).length() < 3) {
                sd += '零';
            }
            sd += digit2chinese(digit % 1000);
        } else if (si.length() == 5) {
            sd += (chineseDigits[digit / 10000] + '萬');
            if (String.valueOf(digit % 10000).length() < 4) {
                sd += '零';
            }
            sd += digit2chinese(digit % 10000);
        }
        return sd;
    }

    /**
     * 压缩字符串
     * @param compress 待压缩字符串
     * @return
     * @throws IOException
     */
    public static String compress(String compress) throws IOException {
        if (isBlank(compress)) {
            return compress;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(compress.getBytes("UTF-8"));
        gzip.close();
        gzip.flush();
        return encode2base64(out.toByteArray());
    }

    /**
     * 解压缩字符串
     * @param uncompress 待解压缩字符串
     * @return
     * @throws IOException
     */
    public static String uncompress(String uncompress) throws IOException {
        if (isBlank(uncompress)) {
            return uncompress;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(decode2base64(uncompress));
        GZIPInputStream gzip = new GZIPInputStream(in);
        byte[] buffer = new byte[256];
        int n = 0;
        while ((n = gzip.read(buffer)) >= 0) {
            out.write(buffer, 0, n);
        }
        out.flush();
        gzip.close();
        return out.toString("UTF-8");
    }

    // 对字节数组字符串进行Base64解码
    public static byte[] toImageArray(String base64img) throws IOException {
        if (base64img == null) // 图像数据为空
        {
            return null;
        }
        if (base64img.startsWith("data:image")) {
            base64img = base64img.substring(base64img.indexOf(',') + 1);
        }
        // Base64解码
        byte[] bytes = decode2base64(base64img);
        for (int i = 0; i < bytes.length; ++i) {
            if (bytes[i] < 0) {// 调整异常数据
                bytes[i] += 256;
            }
        }
        return bytes;
    }

    public static String escapeSql(String str) {
        if (str == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char src = str.charAt(i);
            switch (src) {
                case '\'':
                    sb.append("''");// hibernate转义多个单引号必须用两个单引号
                    break;
                case '\"':
                case '\\':
                    sb.append('\\');
                default:
                    sb.append(src);
                    break;
            }
        }
        return sb.toString();
    }

    public static String ellipsis(String str, int len) {
        if(str.length() > len) {
            str = str.substring(0, len) + "...";
        }
        return str;
    }

    public static String encode2base64str(String str) {
        return encode2base64(trim(str).getBytes(StandardCharsets.UTF_8));
    }

    public static String trim(String str) {
        return str.replaceAll("[\r\n]", "");
    }

    public static String encode2base64(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    public static byte[] decode2base64(byte[] bytes) {
        return Base64.getDecoder().decode(bytes);
    }

    public static byte[] decode2base64(String base64) {
        return Base64.getDecoder().decode(trim(base64).getBytes(StandardCharsets.UTF_8));
    }

    public static String decode2base64str(String base64) {
        return new String(decode2base64(trim(base64).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
    }

    public static List<String> asList(String string) {
        return asList(string, ",");
    }

    public static List<String> asList(String string, String decollator) {
        return Arrays.stream(defaultString(string).split(decollator)).map(String::trim).collect(Collectors.toList());
    }

    public static List<String> asList(String string, Function<String, String> mapper) {
        return Arrays.stream(defaultString(string).split(",")).map(mapper).collect(Collectors.toList());
    }


}
